﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Microsoft.Phone.Controls;

namespace Kiva7.Controls
{
    public class OrientedStackPanel : StackPanel
    {

#region Oriented

        public OrientedStackPanel()
        {
            this.Loaded += OrientedStackPanelLoaded;
        }

        protected PhoneApplicationPage Page
        {
            get
            {
                return GetDependencyObjectFromVisualTree(this, typeof(PhoneApplicationPage)) as PhoneApplicationPage;
            }
        }

        protected DependencyObject GetDependencyObjectFromVisualTree(DependencyObject startObject, Type type)
        {
            DependencyObject parent = startObject;
            while (parent != null)
            {
                if (type.IsInstanceOfType(parent))
                    return parent;
                parent = VisualTreeHelper.GetParent(parent);
            }
            return null;
        }

        protected FrameworkElement FindByName(DependencyObject startObject, string name)
        {
            for(int i=0,
                j = VisualTreeHelper.GetChildrenCount(startObject); 
                i<j; i++)
            {
                DependencyObject dp = VisualTreeHelper.GetChild(startObject, i);
                FrameworkElement fe = dp as FrameworkElement;
                if (fe != null
                    && fe.Name == name)
                {
                    return fe;
                }
                fe = FindByName(dp, name);
                if (fe!= null)
                {
                    return fe;
                }
            }
            return null;
        }

        private void OrientedStackPanelLoaded(object sender, RoutedEventArgs e)
        {
            PhoneApplicationPage page = Page;
            if (page != null)
            {
                ProcessOrientation(page.Orientation);
                page.OrientationChanged += PageOrientationChanged;
            }
        }

        private void PageOrientationChanged(object sender, OrientationChangedEventArgs e)
        {
            ProcessOrientation(e.Orientation);
        }

#endregion

        #region Width

        public double? WidthL
        {
            get { return (double?)GetValue(WidthLProperty); }
            set { SetValue(WidthLProperty, value); }
        }

        // Using a DependencyProperty as the backing store for WidthL.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty WidthLProperty =
            DependencyProperty.Register("WidthL", typeof(double?), typeof(OrientedStackPanel), new PropertyMetadata(null));


        public double? WidthP
        {
            get { return (double?)GetValue(WidthPProperty); }
            set { SetValue(WidthPProperty, value); }
        }

        // Using a DependencyProperty as the backing store for WidthP.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty WidthPProperty =
            DependencyProperty.Register("WidthP", typeof(double?), typeof(OrientedStackPanel), new PropertyMetadata(null));

        #endregion

        #region Height

        public double? HeightL
        {
            get { return (double?)GetValue(HeightLProperty); }
            set { SetValue(HeightLProperty, value); }
        }

        // Using a DependencyProperty as the backing store for HeightL.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HeightLProperty =
            DependencyProperty.Register("HeightL", typeof(double?), typeof(OrientedStackPanel), new PropertyMetadata(null));


        public double? HeightP
        {
            get { return (double?)GetValue(HeightPProperty); }
            set { SetValue(HeightPProperty, value); }
        }

        // Using a DependencyProperty as the backing store for HeightP.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HeightPProperty =
            DependencyProperty.Register("HeightP", typeof(double?), typeof(OrientedStackPanel), new PropertyMetadata(null));

        #endregion

        #region Visibility



        public Visibility? VisibilityL
        {
            get { return (Visibility?)GetValue(VisibilityLProperty); }
            set { SetValue(VisibilityLProperty, value); }
        }

        // Using a DependencyProperty as the backing store for VisibilityL.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty VisibilityLProperty =
            DependencyProperty.Register("VisibilityL", typeof(Visibility?), typeof(OrientedStackPanel), new PropertyMetadata(null));



        public Visibility? VisibilityP
        {
            get { return (Visibility?)GetValue(VisibilityPProperty); }
            set { SetValue(VisibilityPProperty, value); }
        }

        // Using a DependencyProperty as the backing store for VisibilityP.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty VisibilityPProperty =
            DependencyProperty.Register("VisibilityP", typeof(Visibility?), typeof(OrientedStackPanel), new PropertyMetadata(null));

        

        #endregion

        #region Orientation



        public Orientation? OrientationL
        {
            get { return (Orientation?)GetValue(OrientationLProperty); }
            set { SetValue(OrientationLProperty, value); }
        }

        // Using a DependencyProperty as the backing store for OrientationL.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty OrientationLProperty =
            DependencyProperty.Register("OrientationL", typeof(Orientation?), typeof(OrientedStackPanel), new PropertyMetadata(null));



        public Orientation? OrientationP
        {
            get { return (Orientation?)GetValue(OrientationPProperty); }
            set { SetValue(OrientationPProperty, value); }
        }

        // Using a DependencyProperty as the backing store for OrientationP.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty OrientationPProperty =
            DependencyProperty.Register("OrientationP", typeof(Orientation?), typeof(OrientedStackPanel), new PropertyMetadata(null));



        #endregion

        #region Process

        private void ProcessOrientation(PageOrientation orientation)
        {
            if ((orientation & PageOrientation.Landscape) == PageOrientation.Landscape)
            {
                SetAsLandscape();
            }
            else
            {
                SetAsPortrait();
            }
        }

        private void SetAsPortrait()
        {
            if (WidthP.HasValue)
            {
                Width = WidthP.Value;
            }

            if (HeightP.HasValue)
            {
                Height = HeightP.Value;
            }

            if (VisibilityP.HasValue)
            {
                Visibility = VisibilityP.Value;
            }

            if (OrientationP.HasValue)
            {
                Orientation = OrientationP.Value;
            }
        }

        private void SetAsLandscape()
        {
            if (WidthL.HasValue)
            {
                Width = WidthL.Value;
            }

            if (HeightL.HasValue)
            {
                Height = HeightL.Value;
            }

            if (VisibilityL.HasValue)
            {
                Visibility = VisibilityL.Value;
            }

            if (OrientationL.HasValue)
            {
                Orientation = OrientationL.Value;
            }
        }

        #endregion
    }
}
